﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using App1AppHandler;
using Reborn_WorldServer;
using System.Timers;
using Reborn_WorldServer.App1AppHandler.Spells.Interfaces;

namespace Reborn_Server.App1AppHandler
{
    public class Spell_CrystallineWeb : Buff, IInstantCast
    {
        bool busyEnabled = false;

        public Spell_CrystallineWeb()
        {
            minutesLeft = -2;
            spellTimer.Interval = 3000;
        }

        private int getResistPenetration(SpellIcon spIcn)
        {
            return 80;
        }

        private int getTicksBase(SpellIcon sIcon)
        {
            return 7;
        }

        private int getBaseDamage(SpellIcon sIcon)
        {
            return 400;
        }

        override public bool tryResist(SpellIcon _spellIcon, int castLevel, int castInt, int castWis, CreatureBase targetCreatureBase)
        {
            int counter = ticksLeft;
            if (ticksLeft < 1)
                counter = getTicksBase(_spellIcon);

            int penetration = SkillManager.AdjustForCombat(castLevel, getResistPenetration(_spellIcon) * (counter / 2), castInt);

            int resist = targetCreatureBase.getResist(_spellIcon.Skill);

            int result = Managers.GameHandler.random.Next(1, penetration + resist + 1);
            if (result > penetration)
                return true;

            return false;
        }

        override public void Resume(CreatureBase targetCreatureBase, SpellIcon _spellIcon, int timeRemaining, int castLevel, int castCharacterID, int castInt, int castWis, int optionalValue, string xmlData)
        {
            base.Resume(targetCreatureBase, _spellIcon, timeRemaining, castLevel, castCharacterID, castInt, castWis, optionalValue, xmlData);

            if (TargetCreatureBase is Character)
            {
                Character character = (Character)TargetCreatureBase;
                character.SetBusy(true);
                busyEnabled = true;
            }

            if (timeRemaining == -1)
                ticksLeft = getTicksBase(_spellIcon);

            if (timeRemaining != -1)
                ticksLeft = timeRemaining;

            spellTimer.Start();
        }

        override protected void SpellTimer_Expired(object source, ElapsedEventArgs e)
        {
            ticksLeft--;

            LockItem lockitem = TargetCreatureBase.GameHandler.GetLockItem(TargetCreatureBase.MapID, TargetCreatureBase.Instance);
            lock (lockitem.LockObj)
            {
                //This buff has been removed, do nothing (this can occur if the buff gets overwritten exactly when this timer fires)
                if (TargetCreatureBase.buffManager.hasBuff(this.SpellID) == false)
                    return;

                if (TargetCreatureBase.HP < 1)
                {
                    RemoveSpell(true, false);
                    return;
                }

                if (tryResist(spellIcon, CastingCreatureLevel, CastingCreatureInt, CastingCreatureWis, TargetCreatureBase) == true)
                {
                    RemoveSpell(true, true);
                    return;
                }

                if (ticksLeft == 0)
                {
                    RemoveSpell(true, true);
                    return;
                }
                else
                    spellTimer.Start();
            }
        }

        public override void RemoveSpell(bool updateBuffs, bool sendMessage)
        {
            LockItem lockitem = TargetCreatureBase.GameHandler.GetLockItem(TargetCreatureBase.MapID, TargetCreatureBase.Instance);
            lock (lockitem.LockObj)
            {
                if (TargetCreatureBase.buffManager.hasBuff(this.SpellID) == false)
                    return;

                base.RemoveSpell(updateBuffs, sendMessage);

                if (TargetCreatureBase is Character && busyEnabled == true)
                {
                    Character character = (Character)TargetCreatureBase;
                    character.SetBusy(false);
                    busyEnabled = false;
                }

                //Do not do effect if no update (spell is being overwritten)
                if (TargetCreatureBase.HP < 1 || updateBuffs == false)
                    return;

                List<Character> CharactersWithin8 = TargetCreatureBase.currentMapItem.getCharactersWithin8();

                int calculatedDamage = TargetCreatureBase.CalculateGetSpellDamagePerResists(this.getBaseDamage(spellIcon), spellIcon.Skill);

                int absorbedDamage = 0;
                TargetCreatureBase.InflictSpellDamage(calculatedDamage, CastingCharacterID, CastingCreatureGUID, spellIcon.Skill, out absorbedDamage);
                TargetCreatureBase.Update_Character();

                int actualDamage = calculatedDamage - absorbedDamage;

                string targetMessageText = "";
                string casterMessageText = "";

                //Dont send this message if CastingCharacterID && TargetCreatureBase are the same creature
                if (!(TargetCreatureBase is Character && TargetCreatureBase.ID == CastingCharacterID))
                    casterMessageText = TargetCreatureBase.Name + " is shredded by crystalline shards!" + " (" + actualDamage.ToString() + ")";

                targetMessageText = "You are shredded by crystalline shards! (" + actualDamage.ToString() + ")";

                if (absorbedDamage != 0)
                {
                    if (casterMessageText != "")
                        casterMessageText = casterMessageText + " ABSORBED " + absorbedDamage.ToString();
                    if (targetMessageText != "")
                        targetMessageText = targetMessageText + " ABSORBED " + absorbedDamage.ToString();
                }
                if (casterMessageText != "")
                    Managers.GameHandler.TrySendMessage(CastingCharacterID, casterMessageText, "spelldamage");
                if (targetMessageText != "")
                    TargetCreatureBase.SendMessage(targetMessageText, "spelldamaged");

                if (TargetCreatureBase.HP < 1)
                {
                    TargetCreatureBase.SendMessage("You have been slain!", "slain");

                    if (!(TargetCreatureBase is Character && TargetCreatureBase.ID == CastingCharacterID))
                        Managers.GameHandler.TrySendMessage(CastingCharacterID, "You have slain " + TargetCreatureBase.Name + "!", "slay");

                    foreach (Character character in CharactersWithin8)
                    {
                        if (Math.Abs(character.MapX - TargetCreatureBase.MapX) <= 4 && Math.Abs(character.MapY - TargetCreatureBase.MapY) <= 4)
                            character.AddMapItem(TargetCreatureBase.currentMapItem);
                    }
                }
                else
                {
                    foreach (Character character in CharactersWithin8)
                    {
                        if (Math.Abs(character.MapX - TargetCreatureBase.MapX) <= 4 && Math.Abs(character.MapY - TargetCreatureBase.MapY) <= 4)
                            character.AddCreatureBase(TargetCreatureBase);
                    }
                }
            }
        }

        public void InstantCast(CreatureBase castingCreature, CreatureBase targetCreatureBase, SpellIcon _spellIcon, int castLevel)
        {
            if (InitializeInstantCast(castingCreature, targetCreatureBase, _spellIcon, castLevel, false) == false)
                return;

            if (TargetCreatureBase is Character)
            {
                Character character = (Character)TargetCreatureBase;
                character.SetBusy(true);
                busyEnabled = true;
            }

            ticksLeft = getTicksBase(_spellIcon);

            spellTimer.Start();
        }
    }
}
